﻿#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

/// <summary>
/// 2d对象的向量表示
/// </summary>
struct Vector2D {
    double x, y;
    double distanceTo(const Vector2D& other) const {
        return std::sqrt(std::pow(x - other.x, 2) + std::pow(y - other.y, 2));
    }
};

/// <summary>
/// 游戏对象的表示
/// </summary>
struct GameObject {
    int id;
    Vector2D position;
    Vector2D boundingBox; // width and height
    bool intersects(const GameObject& other) const {
        return std::abs(position.x - other.position.x) < (boundingBox.x + other.boundingBox.x) / 2 &&
            std::abs(position.y - other.position.y) < (boundingBox.y + other.boundingBox.y) / 2;
    }
};

/// <summary>
/// 演示游戏开发中的常见操作，包括碰撞检测、寻找最近敌人以及移除屏幕外的对象，并打印相关结果。该函数不接受参数，也不返回值，仅在控制台输出信息。
/// </summary>
void gameDevelopmentDemo() {
    std::vector<GameObject> objects = {
        {1, {0, 0}, {2, 2}},
        {2, {1.5, 1.5}, {1, 1}},
        {3, {5, 5}, {3, 3}},
        {4, {1.8, 1.7}, {0.5, 0.5}}
    };

    GameObject player = { 0, {1, 1}, {1, 1} };

    // 1. 碰撞检测
    std::vector<std::pair<int, int>> collisions;
    for (auto it1 = objects.begin(); it1 != objects.end(); ++it1) {
        for (auto it2 = it1 + 1; it2 != objects.end(); ++it2) {
            if (it1->intersects(*it2)) {
                collisions.emplace_back(it1->id, it2->id);
            }
        }
    }

    // 2. 寻找最近的敌人
    auto nearestEnemy = std::min_element(objects.begin(), objects.end(),
        [&player](const GameObject& a, const GameObject& b) {
            return a.position.distanceTo(player.position) <
                b.position.distanceTo(player.position);
        });

    // 3. 移出屏幕外的对象
    objects.erase(
        std::remove_if(objects.begin(), objects.end(),
            [](const GameObject& obj) {
                return obj.position.x < -10 || obj.position.x > 10 ||
                    obj.position.y < -10 || obj.position.y > 10;
            }),
        objects.end()
    );

    // 打印结果
    std::cout << "Collisions detected:\n";
    for (const auto& [id1, id2] : collisions) {
        std::cout << "Object " << id1 << " collides with object " << id2 << "\n";
    }

    if (nearestEnemy != objects.end()) {
        std::cout << "\nNearest enemy is object " << nearestEnemy->id
            << " at distance " << nearestEnemy->position.distanceTo(player.position) << "\n";
    }

    std::cout << "\nObjects remaining on screen: " << objects.size() << "\n";
}

int main() {
    gameDevelopmentDemo();
    return 0;
}